package net.whzjkj.gateway.core.session;

import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: Mr.Hu
 * @create: 2018-10-31 16:39
 **/
@Slf4j
public class TCPSessionManager implements SessionManager {

	private static volatile TCPSessionManager instance = null;
	// netty生成的sessionID和Session的对应关系
	private Map<String, Session> sessionIdMap;
	// 终端手机号和netty生成的sessionID的对应关系
	private Map<String, String> phoneMap;

	public static TCPSessionManager getInstance() {
		if (instance == null) {
			synchronized (TCPSessionManager.class) {
				if (instance == null) {
					log.info("instance TCPSessionManager");
					instance = new TCPSessionManager();
				}
			}
		}
		return instance;
	}

	public TCPSessionManager() {
		this.sessionIdMap = new ConcurrentHashMap<>();
		this.phoneMap = new ConcurrentHashMap<>();
	}

	@Override
	public boolean containsKey(String sessionId) {
		return sessionIdMap.containsKey(sessionId);
	}

	@Override
	public boolean containsSession(Session session) {
		return sessionIdMap.containsValue(session);
	}

	@Override
	public Session findBySessionId(String id) {
		return sessionIdMap.get(id);
	}

	@Override
	public Session findByTerminalPhone(String phone) {
		String sessionId = this.phoneMap.get(phone);
		if (sessionId == null)
			return null;
		return this.findBySessionId(sessionId);
	}

	@Override
	public synchronized Session put(String key, Session value) {
		if (value.getTerminalPhone() != null && !"".equals(value.getTerminalPhone().trim())) {
			this.phoneMap.put(value.getTerminalPhone(), value.getId());
		}
		return sessionIdMap.put(key, value);
	}

	@Override
	public synchronized Session removeBySessionId(String sessionId) {
		if (sessionId == null)
			return null;
		Session session = sessionIdMap.remove(sessionId);
		if (session == null)
			return null;
		if (session.getTerminalPhone() != null)
			this.phoneMap.remove(session.getTerminalPhone());
		return session;
	}

	@Override
	public Set<String> keySet() {
		return sessionIdMap.keySet();
	}

	@Override
	public void forEach(BiConsumer<? super String, ? super Session> action) {
		sessionIdMap.forEach(action);
	}

	@Override
	public Set<Entry<String, Session>> entrySet() {
		return sessionIdMap.entrySet();
	}

	public List<Session> toList() {
		return this.sessionIdMap.entrySet().stream().map(e -> e.getValue()).collect(Collectors.toList());
	}

}